﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ClusteringWrraper;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        TextWriter _writer = null;
        private int _uid;
        private string _token;
        private int _batchNum;
        private double _prec;
        private LinkedList<FriendsList> _result;
        private LinkedList<FriendsList> _resultForUndo;
        private LoggedInUser _loggedInUser;

        public delegate void TextAppender(string value);

        public Form1()
        {
            InitializeComponent();
            Load += Form1_Load;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _writer = new TextBoxStreamWriter(textBox1);
            Console.SetOut(_writer);
            Write("Press Start...");
        }


        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";

            _uid = textBoxUID.Text == "" ? 665778366 : Int32.Parse(textBoxUID.Text);

            _batchNum = textBoxBatch.Text == "" ? 10 : Int32.Parse(textBoxBatch.Text);

            _token = textBoxToken.Text == ""
                         ? "182806151738475|2.fONVS0GBJtHkR2IvW8pA9w__.3600.1301317200-665778366|wrEE88QlvToj9adb3J8JTkdqDOU"
                         : textBoxToken.Text;

            _prec = textBoxPrec.Text == "" ? 0.0001 : Double.Parse(textBoxPrec.Text);

            _result = new LinkedList<FriendsList>();
            _resultForUndo = new LinkedList<FriendsList>();

            Directory.CreateDirectory("OUT");
            Directory.CreateDirectory("IN");

            var worker = new Thread(Start);
            worker.Start();
        }

        private void Start()
        {
            string errMsg;
            Write("Working...");
            
            _loggedInUser = new LoggedInUser(_token, _uid, _batchNum, _prec);
            
            var startTime = DateTime.Now;
            
            _loggedInUser.RunClustering(out errMsg);

            foreach (var subGroup in _loggedInUser.GetGroups())
            {
                _result.AddLast(subGroup);
            }

            if (_result == null)
            {
                Write("ERROR - Operation was not completed");
                return;
            }

            var endTime = DateTime.Now;
            Write(string.Format("Finished algo' now saving... Total Seconds: {0}", endTime.Subtract(startTime).TotalSeconds));
            
            PrintResult();

            endTime = DateTime.Now;
            Write(string.Format("Finished all!!! Total Seconds: {0}", endTime.Subtract(startTime).TotalSeconds));
        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void GroupAGroup(object sender, EventArgs e)
        {
            if (_result == null || textBoxGroupIndex.Text == "" || _loggedInUser == null)
            {
                return;
            }

            _resultForUndo = new LinkedList<FriendsList>();
            foreach (var element in _result)
            {
                _resultForUndo.AddLast(element);
            }

            var groupIndex = Int32.Parse(textBoxGroupIndex.Text);

            if (groupIndex >= _result.Count)
                return;

            var selectedGroup = _result.ElementAt(groupIndex);
            var node = _result.Find(selectedGroup);
            if (node == null)
            {
                return;
            }

            selectedGroup.ClusterList();

            var groupSubGroups = selectedGroup.SubLists;

            foreach (var subGroup in groupSubGroups)
            {
                _result.AddAfter(node,subGroup);
            }

            _result.Remove(selectedGroup);

            PrintResult();
        }

        private void buttonUndo_Click(object sender, EventArgs e)
        {
            _result = new LinkedList<FriendsList>();
            foreach (var element in _resultForUndo)
            {
                _result.AddLast(element);
            }
            PrintResult();
        }

        private void PrintResult()
        {
            SetText("");
            var counter = 0;
            foreach (var list in _result)
            {
                Write(string.Format("\r\nGroup {0}:{1}",
                    counter,
                    list.ToString()));
                counter++;
            }

            Write("\r\nLonely Friends:" + _loggedInUser.GetLonelyFriends().ToString());
        }

        private void Write(String str)
        {
            textBox1.Invoke(new UpdateTextCallback(UpdateText), str);
        }

        private void SetText(String str)
        {
            textBox1.Invoke(new UpdateTextCallback(OverwriteText), str);
        }

        private void UpdateText(string text)
        {
            text = text.Replace("\n", Environment.NewLine);
            text += Environment.NewLine;
            // Set the textbox text.
            textBox1.Text += text;
        }

        private void OverwriteText(string text)
        {
            text = text.Replace("\n", Environment.NewLine);
            text += Environment.NewLine;
            // Set the textbox text.
            textBox1.Text = text;
        }

        public delegate void UpdateTextCallback(string text);

        private void buttonCreateFbList_Click(object sender, EventArgs e)
        {
            if (_result == null || textBoxGroupIndex.Text == "" || _loggedInUser == null)
            {
                return;
            }

            var groupIndex = Int32.Parse(textBoxGroupIndex.Text);

            if (groupIndex >= _result.Count)
                return;

            var selectedGroup = _result.ElementAt(groupIndex);

            selectedGroup.Name = selectedGroup.First().Value.Name + "'s Group";

            var kvp = new KeyValuePair<string,string>("name",selectedGroup.Name);
            var list = new LinkedList<KeyValuePair<string, string>>();
            list.AddFirst(kvp);

            var res = QueryHelper.HttpPost(_token, @"https://graph.facebook.com/me/friendlists", list);

            Console.WriteLine(res);
        }

        private void buttonPostToWalls_Click(object sender, EventArgs e)
        {
            if (_result == null || textBoxGroupIndex.Text == "" || _loggedInUser == null)
            {
                return;
            }

            var groupIndex = Int32.Parse(textBoxGroupIndex.Text);

            if (groupIndex >= _result.Count)
                return;

            var selectedGroup = _result.ElementAt(groupIndex);

            selectedGroup.PostToGroupWallsWithRestApi(_token,textBoxPostToWalls.Text);
        }
    }
}
